Skip to content

Emit identifiable error frames on the direct-write path (MJ-16)#89

Merged
jonasniesner merged 1 commit into
OpenDisplay:mainfrom
balloob:fix/identifiable-error-frames
Jul 6, 2026
Merged

Emit identifiable error frames on the direct-write path (MJ-16)#89
jonasniesner merged 1 commit into
OpenDisplay:mainfrom
balloob:fix/identifiable-error-frames

Conversation

@balloob

@balloob balloob commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

What

The compressed direct-write path emitted generic {0xFF, 0xFF} error frames, making the failing command unidentifiable. The published spec says error frames are 0xFF followed by the command code ({0xFF, cmd}). This makes the firmware conform: the second byte now carries the failing command's low byte, so the frame identifies which command failed. This matches the already-present {0xFF, 0x72} gray4-END frame in the same file.

Sites changed (src/display_service.cpp)

Handler Failure New frame Command
handleDirectWriteCompressedData length-overflow guard {0xFF, 0x71} DATA
handleDirectWriteCompressedData zlib-stream failure {0xFF, 0x71} DATA
handleDirectWriteStart decompressed-size mismatch {0xFF, 0x70} START
handleDirectWriteStart initial zlib-stream failure {0xFF, 0x70} START
handlePartialWriteStart zero logical-size guard {0xFF, 0x76} PARTIAL START
handleDirectWriteEnd compressed final-flush failure {0xFF, 0x72} END

Frames stay 2 bytes; only the second byte changed. No {0xFF, 0xFF} emissions remain in the file.

Backward compatibility

Pairs with py-opendisplay PR #120. Its is_compressed_failure_frame() accepts both {0xFF, 0xFF} and the spec-conformant {0xFF, 0x70}, so the compressed-START fallback keeps working regardless of which frame the firmware sends. The DATA/END/partial frames were never valid ACKs, so updated clients raise the same typed protocol error as before — now with the command identified. The website direct-write handler (PR #28) treats any leading-0xFF frame as an error.

Testing

  • pio run -e nrf52840custom — SUCCESS
  • pio run -e esp32-c3-N4 — SUCCESS

🤖 Generated with Claude Code

https://claude.ai/code/session_012g2e8mr132vcizx92WsgiR

MJ-16: The compressed direct-write path emitted generic {0xFF, 0xFF} error
frames, so a failing command was unidentifiable. The published spec says error
frames are 0xFF followed by the command code ({0xFF, cmd}). Make the firmware
conform by setting the second byte to the failing command's low byte, matching
the existing {0xFF, 0x72} gray4 END frame.

Sites (src/display_service.cpp):
- handleDirectWriteCompressedData length-overflow guard -> {0xFF, 0x71} (DATA)
- handleDirectWriteCompressedData zlib-stream failure    -> {0xFF, 0x71} (DATA)
- handleDirectWriteStart decompressed-size mismatch      -> {0xFF, 0x70} (START)
- handleDirectWriteStart initial zlib-stream failure     -> {0xFF, 0x70} (START)
- handlePartialWriteStart zero logical-size guard        -> {0xFF, 0x76} (PARTIAL START)
- handleDirectWriteEnd compressed final-flush failure    -> {0xFF, 0x72} (END)

Backward-compatible with updated clients: py-opendisplay PR #120's
is_compressed_failure_frame() accepts both {0xFF, 0xFF} and {0xFF, 0x70} for the
compressed-START fallback, and the website direct-write handler (PR OpenDisplay#28) treats
any leading-0xFF frame as an error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012g2e8mr132vcizx92WsgiR
@balloob balloob requested a review from jonasniesner as a code owner July 6, 2026 06:31
@jonasniesner jonasniesner merged commit f98ec0d into OpenDisplay:main Jul 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants